#include "_Luly.h"

#ifdef _ANDROID_PLATFORM__
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_ttf.h"
#else
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_ttf.h>
#endif

#include "Luly.h"
#include "UI/_UI.h"
#include "_SoundEffect.h"

//初始化载入
void _Luly::init_load() {
  _UI::getInstance().defaultFont =
      Font("resources/font/fusion-pixel.otf", 12, "fusion-pixel");
  _UI::getInstance().button_default_ninePatch = NinePatch(
      Image("resources/image/button_default_30x30_9patch.png", "_bd_30x30_9patch_"));
  _UI::getInstance().button_hovering_ninePatch = NinePatch(
      Image("resources/image/button_hovering_30x30_9patch.png", "_bh_30x30_9patch_"));
  _UI::getInstance().button_clicked_ninePatch = NinePatch(
      Image("resources/image/button_clicked_30x30_9patch.png", "_bc_30x30_9patch_"));
  _UI::getInstance().panel_60x60_ninePatch =
      NinePatch(Image("resources/image/panel_60x60_9patch.png", "_panel_60x60_9patch_"));
  _UI::getInstance().progressBar_background_ninePatch =
      NinePatch(Image("resources/image/progressBar_background_12x12.png",
                      "_progrbar_background_12x12_9patch_"));
  _UI::getInstance().progressBar_front_ninePatch = NinePatch(Image(
      "resources/image/progressBar_front_12x12.png", "_progrbar_front_12x12_9patch_"));
  _UI::getInstance().checkbox_box_default_image =
      Image("resources/image/checkBox_box_default_12x12.png", "_ckbox_bd_12x12_img_");
  _UI::getInstance().checkbox_check_default_image =
      Image("resources/image/checkBox_check_default_12x12.png", "_ckbox_cd_12x12_img_");
  _UI::getInstance().checkbox_check_checked_image = Image(
      "resources/image/checkBox_check_checked_12x12.png", "_ckbox_cchecked_12x12_img_");
}

void _Luly::init() {
  SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS);
  Mix_Init(MIX_INIT_MP3 | MIX_INIT_OGG);
  TTF_Init();
  IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF |
           IMG_INIT_WEBP);  //支持加载jpg,png,tif,webp图像文件

  Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS,
                4096);
  _SoundEffect::getInstance().init();
  //默认资源先于Luly::init()载入，
  //因为如果默认资源后于Luly::init()再入，会覆盖掉Luly::init()的修改（比如setDefaulFont)
  init_load();

  p_window = SDL_CreateWindow(
      title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
      windowWidth, windowHeight,
      isFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE);
  Luly::init();

  p_renderer = SDL_CreateRenderer(p_window, -1, SDL_RENDERER_ACCELERATED);

  _UI::getInstance().init();

  currentFPS = maxFPS;
}

void _Luly::event() {
  // while (isRunning) {
  while (SDL_PollEvent(&(_Luly::getInstance().current_event))) {
    switch (current_event.type) {
      case SDL_QUIT:
        isRunning = false;
        break;
      case SDL_APP_TERMINATING:
        //如果结束
        break;
      case SDL_APP_WILLENTERBACKGROUND:
        //如果进入后台
        break;
      case SDL_APP_WILLENTERFOREGROUND:
        //如果进入前台
        //更新fps计时点
        fps_start = std::chrono::system_clock::now().time_since_epoch();
        break;
    }
    if (current_event.window.event == SDL_WINDOWEVENT_RESIZED) {
      //更新可视宽高
      SDL_GetWindowSize(p_window, &windowWidth, &windowHeight);
      windowHeight /= scale;
      windowWidth /= scale;
    }
    Luly::event();
    _UI::getInstance().event();
  }
}

void _Luly::update() {
  // while (isRunning) {
  Luly::update();
  _UI::getInstance().update();
  // }
}

void _Luly::draw() {
  fps_start = std::chrono::system_clock::now().time_since_epoch();
  std::chrono::nanoseconds deltaTime;
  std::chrono::nanoseconds duration(1000000000 / maxFPS);
  //初始化可视宽高
  SDL_GetWindowSize(p_window, &windowWidth, &windowHeight);
  windowHeight /= scale;
  windowWidth /= scale;
  while (isRunning) {
    event();
    update();
    // std::this_thread::sleep_for(duration);
    deltaTime = std::chrono::system_clock::now().time_since_epoch() - fps_start;

    if (deltaTime >= duration) {
      SDL_RenderClear(p_renderer);

      _UI::getInstance().draw();
      Luly::draw();
      SDL_RenderSetScale(p_renderer, (float)scale, (float)scale);
      SDL_RenderPresent(p_renderer);
      currentFPS =
          (std::chrono::nanoseconds(1000000000) / double(deltaTime.count()))
              .count();
      fps_start = std::chrono::system_clock::now().time_since_epoch();
      //动态修正帧率（会在maxFPS上下浮动,除非实在卡到修不了）
      //=============================
      if (deltaTime > std::chrono::nanoseconds(1000000000 / maxFPS)) {
        duration -= deltaTime - std::chrono::nanoseconds(1000000000 / maxFPS);
      } else if (deltaTime < std::chrono::nanoseconds(1000000000 / maxFPS)) {
        duration += std::chrono::nanoseconds(1000000000 / maxFPS) - deltaTime;
        ;
      }
      //=============================
    }
  }
}

_Luly::~_Luly() {
  SDL_DestroyRenderer(p_renderer);
  SDL_DestroyWindow(p_window);
  TTF_Quit();
  IMG_Quit();
  Mix_CloseAudio();
  SDL_Quit();
}

double Luly::getFPS() { return _Luly::getInstance().currentFPS; }

void Luly::setTitle(std::string title) {
  _Luly::getInstance().title = title;
  SDL_SetWindowTitle(_Luly::getInstance().p_window, title.c_str());
}
//整数倍效果更佳
void Luly::setScale(double scale) { _Luly::getInstance().scale = scale; }

//如果不设置,默认为60帧
void Luly::setMaxFPS(unsigned int maxFPS) {
  _Luly::getInstance().maxFPS = maxFPS;
}

//设置窗口宽高（安卓端不起作用）
void Luly::setWindowWH(int width, int height) {
#ifndef _ANDROID_PLATFORM__
  _Luly::getInstance().windowWidth = width;
  _Luly::getInstance().windowHeight = height;
  SDL_SetWindowSize(_Luly::getInstance().p_window, width, height);
  SDL_SetWindowPosition(_Luly::getInstance().p_window, SDL_WINDOWPOS_CENTERED,
                        SDL_WINDOWPOS_CENTERED);
#endif
}

int Luly::getWindowWidth() { return _Luly::getInstance().windowWidth; }

int Luly::getWindowHeight() { return _Luly::getInstance().windowHeight; }

//设置窗口宽高（安卓端无意义）
void Luly::setFullScreen(bool isFullScreen) {
  SDL_SetWindowFullscreen(
      _Luly::getInstance().p_window,
      isFullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_RESIZABLE);
}